{
  LW Sceneeditor -- LightWave Scene Editor services

  Based on lwsceneeditor.h which is:
  Copyright 2003, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}
unit LW_Sceneeditor;

{$mode objfpc}{$H+}

interface

uses
  LW_Types  ,
  {$Warning : Uncomment after implement lwpanel.pas}
  // LW_Panel  ,
  LW_Render ;

const
  LWSCENEEDITOR_GLOBAL = 'SceneEditorGlobal' ;

  // enum en_SEColumnRequests
  { Your envelope() function will get one of these requests: }
  SECOLUMNREQUEST_STATE  =  0 ; // Request the enveloped state.  This should be one of SEENV_NOT_ENVELOPABLE, SEENV_NOT_ENVELOPED or SEENV_ENVELOPED
  SECOLUMNREQUEST_APPLY  =  1 ; // This cell can be enveloped, but currently is not.  Return SEENV_NOT_ENVELOPED or SEENV_ENVELOPED
  SECOLUMNREQUEST_REMOVE =  2 ; // This cell is currently enveloped.  Return SEENV_NOT_ENVELOPED or SEENV_ENVELOPED

  { These flags indicate the behavior and drawing state of a cell (a specific value within a column) }
  SECELLFLAG_ENABLED        = 1 shl 0 ; // Cell can be interacted with by user and is editable at the moment
  SECELLFLAG_EXISTS         = 1 shl 1 ; // Cell exists, rather than blank.  Cells that exist and are enabled can be selected
  SECELLFLAG_READONLY       = 1 shl 2 ; // Cell can be viewed and interacted with but it not editable
  SECELLFLAG_CANHAVECHANNEL = 1 shl 3 ; // Cell can have a channel attached (envelopable)
  SECELLFLAG_CANHAVETEXTURE = 1 shl 4 ; // Cell can have a texture applied (texturable)

  // enum en_SEBaseTypes
  { These are data types for matching with item types internally supported for selection. }
  SEBASETYPE_UNKNOWN        =   0 ; // item should be NULL (not used)
  SEBASETYPE_SCENE          =   1 ; // item is name of scene (char*) (not used)
  SEBASETYPE_ITEM           =   2 ; // item is a LWItemID
  SEBASETYPE_SURFACEGROUP   =   3 ; // item is name of group (char*)
  SEBASETYPE_SURFACE        =   4 ; // item is a LWSurfaceID
  SEBASETYPE_CHANNELGROUP   =   5 ; // item is a LWChanGroupID
  SEBASETYPE_CHANNEL        =   6 ; // item is a LWChannelID
  SEBASETYPE_IMAGE          =   7 ; // item is a LWImageID (not used)
  SEBASETYPE_TEXTURECONTEXT =   8 ; // item is a LWTxtrContextID (not used)
  SEBASETYPE_TEXTURE        =   9 ; // item is a LWTextureID (not used)
  SEBASETYPE_TEXTURELAYER   =  10 ; // item is a LWTLayerID (not used)
  SEBASETYPE_ENVELOPE       =  11 ; // item is a LWEnvelopeID (not used)
  SEBASETYPE_VIEWPORT       =  12 ; // item is a view port 0-based index (not used)
  SEBASETYPE_PARTICLESYSTEM =  13 ; // item is a LWPSysID (not used)
  SEBASETYPE_AUDIO          =  14 ; // item is an audio track LWAudioTrackID (not used)
  SEBASETYPE_VIDEO          =  15 ; // item is an video track LWVideoTrackID (not used)

  { The following are predefined column types.  IDs starting with undescores
      are reserved for future use.  If you want to make a custom type, be sure
      to provide a custom interface and custom draw callbank.                  }
    { Datatype   - Description }
  function SECOLTYPE_TOGGLE   : TLWID ; //  int       -  Checkbox or similar toggle (Unseen By Camera, Cast Shadows)
  function SECOLTYPE_INTEGER  : TLWID ; //  int       -  Integer based control (Subpatch Level, Area Light Quality
  function SECOLTYPE_PERCENT  : TLWID ; //  double    -  Floating point number displayed as a percentage.  1.0 is 100% (Light Intensity, Blur Lrngth)
  function SECOLTYPE_DISTANCE : TLWID ; //  double    -  Floating point number displayed as a distance in meters (Focal Distance, Light Range)
  function SECOLTYPE_ANGLE    : TLWID ; //  double    -  Floating point number displayed as an angle in degrees (Heading Limits, Light Cone Angle)
  function SECOLTYPE_TIME     : TLWID ; //  double    -  Floating point number displayed as a time in seconds
  function SECOLTYPE_FLOAT    : TLWID ; //  double    -  Floating point number (Anti-Aliasing Threshold, Metaball Resolution)
  function SECOLTYPE_LIST     : TLWID ; //  int       -  Pre-determined list of items.  Must provide list callbacks (Item Visibility, Subdivision Order)
  function SECOLTYPE_FILE     : TLWID ; //  char *    -  Text string representing a file (PFX File)
  function SECOLTYPE_STRING   : TLWID ; //  char *    -  Text string (Item Name, Comment)
  function SECOLTYPE_COLOR    : TLWID ; //  float[3]  -  RGB Color Triple (Light Color, Edge Color)
  function SECOLTYPE_ITEM     : TLWID ; //  LWItemID  -  ID of an item (IK Goal, Parent).
  function SECOLTYPE_IMAGE    : TLWID ; //  LWImageID -  ID of an image (Projection Image)
  function SECOLTYPE_VMAP     : TLWID ; //  SEVMap * -  Name of a VMAP (e.g. Bone Weight Map).

type
  { Used by SECOLTYPE_VMAPs, since both a type and a name are needed to identify a VMap }
  PSEVMap =^TSEVMap ;
  TSEVMap = record
    Type_ : TLWID ; // VMap Type.  See lwmeshes.h for common types.
    Name  : PChar ; // VMap Name                                     // const
  end;

  { This structure holds an item identifier and its associated value.
    It is used in the column apply function.                            }
  PSEApply = ^TSEApply ;
  TSEApply = record
    Item   ,
    Value  : Pointer ;
  end;

  { Used in TSEColumn.Apply }
  TProgressIncrementFunc = procedure ( const Void ) ;

  { Provides details about a specific column within a bank
    A column can only operate on one SEBASETYPE            }
  PPSEColumn  = ^PSEColumn;
  PSEColumn   = ^TSEColumn ;
  TSEColumn   = record
    { Column Title. }
    Title       : PChar ;

    { Column Type.
      Use LWID_() to generate one, or use one of the
      predefined column types above }
    Datatype    : TLWID ;

    { Column Comment.
      This will be displayed on the status line when a cell is selected  }
    Description : PChar;

    { This gains access to an envelope that may be attached to this cell.
      The return value is a NULL-terminated array of channel ids associated
      with this cell.
      The request parameter is used to determine if a channel should be added
      or removed on simply query the existence of a channel.
      Channels differ from envelopes in that they also can contain modification
      plugins and exist within a channel hierarchy.
      Envelopes are the lower level storage of key frames.
      A channel contains an envelope.
      Color channels are an example of 3 channels in the array.
      Most other types will only return zero or one channel.
      Zero channels can return NULL for the array or NULL
      as the first element in the array.     }
    Channels    : function
                  (       Item    : Pointer ;
                          // Request parameter originally TSEColumnRequests enum
                          Request : Integer ) : PLWChannel ;

    { Flags Function.
      SE calls this to decide how to draw the control and how it should interact
      with the keyboard and mouse.
      This should return the various listed flag bits.
      Can be NULL if always ENABLED and EXISTS and NOT READONLY
      The id passed in is data dependent on the type of data
      this column can work with.
      For 'Layout' types, it is an LWItemID; for 'Channel' types,
      it is a LWChannelID; for 'Surface' types, it is a LWSurfaceID.  }
    Flags       : function
                  (       Item     : Pointer ) : UInt32 ;

    { Query Function.
      Scene Editor calls this to get the current value(s) of this cell  }
    Query       : procedure
                  (       Item     : Pointer ;
                          Time     : TLWTime ;
                          Value    : Pointer );

    { Apply Function.
      Scene Editor calls this to change the value of one or more items
      in this column.
      This can occur when multiple cells are selected.
      This function pointer can be NULL if the flags() function
      never returns SECELLFLAG_ENABLED and is thus never evaluated.
      The items parameter is really an array of item/value combinations.
      This function is not called when in preview mode.
      This can be slow if this causes a lot of dependent updates.
      It is up to the function to decide the quickest
      approach to setting the appropriate values.
      The return value is the number of items successfully altered.
      So, this would be zero if no items were changed. }
    Apply       : function
                  (       Time     : TLWTime ;
                          Numitems : UInt32  ;
                          Items    : PSEApply ;
                          progressincfunc : TProgressIncrementFunc ) : UInt32 ;

    { Comparision Function.  Scene Editor calls this when sorting by column.
      Return value is simialr to
      QSort:  0 means identical,
              -1 means value1 < value2,
              1 means value1 > value2
      Can be NULL     }
    Compare     : function
                  (       Value1   ,
                          Value2   : Pointer ) : Integer ;

    { choice list construction  }
    { For SECOLTYPE_LIST's, returns the number of items in the list;
      for other types this can be NULL.
      If item is LWI_NULL, return all possible items                                              }
    ListCount   : function
                  (       Item     : Pointer ) : Integer ;

    { For SECOLTYPE_LIST's, returns the name of the index item in the list;
      for other types this can be NULL.
      If item is LWI_NULL or row is -1,
      return a complete list of all possible options }
    ListName    : function
                  (       Item     : Pointer ;
                          Index    : Integer ) : PChar ; // const

    { For SECOLTYPE_ITEM, SECOLTYPE_IMAGE and SECOLTYPE_VMAP's,
      used to ask if this item is OK for a particular item.
      Use this to limit the item list to only lights, for example
      This can also be used to limit the allowed range of a value
      to between 0.0 to 1.0.
      Returns 1 if the quereied item is valid, even if the queried item was altered.
      testItem() should return a zero-terminated array of allowed
      VMap types [ie: ( LWVMAP_WGHT, 0 )] if the test value is LWI_NULL }
    TestItem    : function
                  (       Item     ,
                          Value    : Pointer ) : Integer ;

    { Jump To function.  This should present the standard interface for editing this option.
      For example, a Controller and Limits option could open the Motion Options panel     }
    JumpTo      : procedure
                  (       Item     : Pointer ) ;

    { Provides a raster that you can draw custom cell contents within.
      a value of NULL is used when the column title should be drawn instead of an actual cell.
      Return 0 to have Scene Editor draw the control itself; otherwise 1;    }
    {$Warning : Uncomment after implement lwpanel.pas}
    //CustomDraw  : function
    //              (       Value    : Pointer   ;
    //                      Raster   : PLWRaster ;
    //                      Left     ,
    //                      Top      : Integer   ;
    //                      Width    ,
    //                      Height   ,
    //                      Flags    : UInt32    ) : Integer ;

    { XPanel interface used by IMPCOLTYPE_CUSTOM columns; others can leave this blank  }
    // CustomPanel : LWXPanelID ;

    { texture access  }
    { This gains access to a texture array that may exist for the cell in the column.
    the request mode can ask to add a texture, remove an existing texture, or find out if a texture currently exists (or is even possible)  }
    Texture     : function
                  (       Item     : Pointer ;
                          // Request parameter originally TSEColumnRequests enum
                          Request  : Integer ) : PLWTexture;
  end;

  { Provides details about a bank
    A bank acts on a specific type of data: item, channel, or surface
    Therefore, all columns in a bank are intended to on that same type of data. }
  PSEBank = ^TSEBank ;
  TSEBank = record
    //Bank ID.  Use the LWID_() macro to convert a string into an ID.
    ID        : TLWID      ;
    // Name of category this bank belongs to.  can be NULL.  Banks with same category name are grouped together
    Category  ,
    // Bank Title, for display purposes.  Used in the Bank Popup. Also used to organize column selection
    Title     : PChar      ;
    // Bank base.  Determines what the bank acts on (layout items, channels, surfaces). Originally TSEBaseTypes.
    Base      : Integer    ;
    // NULL-terminated array of columns in the bank
    Columns   : PPSEColumn ;
    // Num Rows Function. Scene Editor calls this to ask how many rows this bank needs for this item ID
    //NumRows   : function
    //            (       BankID : UInt32 ;
    //                    ID     : Pointer ) : Integer ;
    // Called before Scene Editor calls any query/evaluate functions.  Use this to get bank-specific globals, init arrays, etc.
    BeginProcess : procedure
                   (       BankID :  TLWID ) ;
    // Called after Scene Editor has called all the query/evalute functions.  Use this to free whatever you got during beginProcess()
    EndProcess   : procedure
                   (       BankID :  TLWID ) ;
  end;

  { This is returned by the Scene Editor Global for use by your plug-in
    Banks need to be registered so that the scene editor can manipulate
    the data in your plug-in server.
    Each bank should will on a specific type of data.
    Currently, only Layout Items, Channels, and Surfaces are supported.
    So, as long as your plug-in data has a direct association with these
    data types, the scene editor can work with it.
    A master bank differs from a normal bank in that it will automatically be
    applied when the scene editor is first activated (used)                   }
  PSceneEditorGlobal = ^TSceneEditorGlobal ;
  TSceneEditorGlobal = record
    // Register a new bank with the Scene Editor.  You cannot register the same ID twice
    RegisterBank         : function
                           (       Bank    : PSEBank       ) : Integer ;
    // Unregister an existing bank from the Scene Editor.
    UnregisterBank       : function
                           (       BankID  : TLWID         ) : Integer ;
    // Register a new bank master with Scene Editor.
    // This plug-in will be launched automatically when the scene Editor is
    // first activated.  Returns 1 on succes, -1 if already added and 0 on error
    RegisterBankMaster   : function
                           ( const MasterName : PChar      ) : Integer ;
    // Unregister a bank master.
    // Returns 1 on succes, -1 if already added and 0 on error
    UnregisterBankMaster : function
                           ( const MasterName : PChar      ) : Integer ;
    // Return number of instances of the Scene Editor running
    NumInstances         : function
                           ( const Void                    ) : UInt32  ;
    // Issue a command to the Scene Editor global service.  Returns 0 on error
    { Available commands include:
        SE_Refresh <instance>    : Ask a Scene Editor instance to refresh it's
                                   interface.
	SE_OpenWindow <instance> : Attempts to open the Scene Editor instance window.
                                   It will fail if the window does not open,
                                   but success if it was already open.
	SE_CloseWindow( instance>: Attempts to close the Scene Editor instance
                                   window.  It will success if the window was
                                   already closed.                             }
    Command              : function
                           ( const CommandString     : Pchar   ;
                                   // The return data is dependent on the command,
                                   // and it allows the command to return data
                                   // back to the caller.
	                           // It can be NULL if not required.
                                   CommandReturnData : Pointer  ) : Integer ;
  end;


implementation

function SECOLTYPE_TOGGLE: TLWID;
begin
  Result := LWID_( '_', 'T', 'G', 'L' ) ;
end;

function SECOLTYPE_INTEGER: TLWID;
begin
  Result := LWID_( '_', 'I', 'N', 'T' ) ;
end;

function SECOLTYPE_PERCENT: TLWID;
begin
  Result := LWID_( '_', 'P', 'C', 'T' ) ;
end;

function SECOLTYPE_DISTANCE: TLWID;
begin
  Result := LWID_( '_', 'D', 'S', 'T' ) ;
end;

function SECOLTYPE_ANGLE: TLWID;
begin
  Result := LWID_( '_', 'A', 'N', 'G' ) ;
end;

function SECOLTYPE_TIME: TLWID;
begin
  Result := LWID_( '_', 'S', 'E', 'C' ) ;
end;

function SECOLTYPE_FLOAT: TLWID;
begin
  Result := LWID_( '_', 'F', 'L', 'T' ) ;
end;

function SECOLTYPE_LIST: TLWID;
begin
  Result := LWID_( '_', 'L', 'S', 'T' ) ;
end;

function SECOLTYPE_FILE: TLWID;
begin
  Result := LWID_( '_', 'F', 'I', 'L' ) ;
end;

function SECOLTYPE_STRING: TLWID;
begin
  Result := LWID_( '_', 'S', 'T', 'R' ) ;
end;

function SECOLTYPE_COLOR: TLWID;
begin
  Result := LWID_( '_', 'C', 'L', 'R' ) ;
end;

function SECOLTYPE_ITEM: TLWID;
begin
  Result := LWID_( '_', 'I', 'T', 'M' ) ;
end;

function SECOLTYPE_IMAGE: TLWID;
begin
  Result := LWID_( '_', 'I', 'M', 'G' ) ;
end;

function SECOLTYPE_VMAP: TLWID;
begin
  Result := LWID_( '_', 'V', 'M', 'P' ) ;
end;

end.

